﻿using UnityEngine;
using System.Collections;

// 回调函数
// int : 
//          0、下载成功。
//          1、超时
//          2、下载有error。
using Callback = System.Action<DownloadResult, byte[]>;


/// <summary>
/// 文件下载器
///     负责从指定url下载文件，同时返回三种结果 成功， 超时， 失败
///     
/// </summary>
public class FileDownloadMgr : MonoBehaviour {

    
    static FileDownloadMgr s_instance;

    ScheduleObject msch = ScheduleObject.Create();

	void Awake()
    {
        Debugger.Assert(s_instance == null, "logic error! s_instance must be null");
        s_instance = this;
    }

    void Update()
    {
        msch.Update(RealTime.deltaTime);
    }

    void OnDestroy()
    {
        Debugger.Assert(s_instance == this , "logic error ! s_instance must not be null");
        s_instance = null;
    }

    /// <summary>
    /// 游戏启动后添加该组建至单一实例上;
    /// </summary>
    public static void SetUp()
    {

        var singInsttance = Global.FindSingInstance();
        if (singInsttance)
        {
            singInsttance.AddComponent<FileDownloadMgr>();
        }

    }

    // 开始下载文件
    // outTime 超时时间
    public static void Download(string url, System.Action<DownloadResult, WWW> cb, float outTime = 3)
    {
        Debugger.Assert(s_instance != null, "must call SetUp at the start of game");
        if (s_instance == null) return;

        s_instance.StartCoroutine(s_instance._startDownloadFile(url, cb, outTime));
    }



    private static string _defaultPath = "http://www.chiyugames.com/Huluwa/";
    /// <summary>
    /// 获取ftp服务器文件位置
    /// </summary>
    public static string DefaultPath
    {
        get
        {
            return _defaultPath + CompileConfig.Instance.bundleVersion;
        }
    }


    IEnumerator _startDownloadFile(string url, System.Action<DownloadResult, WWW> cb, float outTime)
    {
        bool hasTimeOunt = false;
        msch.AddSchedule(outTime, () => { hasTimeOunt = true; });
        using (WWW www = new WWW(url))
        {
            while ((!www.isDone) && !hasTimeOunt) 
            {
                yield return null;
            }

            msch.Clear();

            do
            {
                // 超时
                if (hasTimeOunt)
                {
                    Debugger.Log(string.Format("download file failed from {0} with error : {1}", url, www.error));
                    cb( DownloadResult.TimeOut, www);
                    break;
                }

                bool noError = string.IsNullOrEmpty(www.error);
                Debugger.Assert(noError, "down load version error form : " + url);
                if (noError)
                {
                    Debugger.Log(string.Format("download file success form :{0}", url));
                    cb( DownloadResult.Success, www);
                    break;
                }

                cb(DownloadResult.Error, www);
                Debugger.Log(string.Format("download file failed from {0} with error : {1}", url, www.error));
            } while (false);

            yield return null;
        }
    }
}

public enum DownloadResult
{
    Success = 0,
    TimeOut = 1,
    Error = 2,
}
